{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 面向对象\n",
    "- oop思想\n",
    "    - 接触到一个任务，首先想到的是任务的构成，是由模型构成\n",
    "- 几个名词\n",
    "    - oo：面向对象的分析\n",
    "    - OOA：面向对象的分析\n",
    "    -OOD：面向对象的设计\n",
    "    - OOI：xxx的实现\n",
    "    - OOP：xxx的编程\n",
    "    - OOA->OOD->OOI:面向对象的实现过程\n",
    "- 类和对象的概念\n",
    "    - 类：抽象名词，代表一个集合，有共性的事物\n",
    "    - 对象：具象的事物，单个个体\n",
    "    - 类和对象的关系\n",
    "        - 一个具象代表一个事物的某一个个体\n",
    "        - 一个是抽象，代表一大类事物\n",
    "- 类中的内容，应该具有两个内容\n",
    "    - 表明事物的特征，叫做属性（变量）\n",
    "    - 表明的事物功能或动作，称为成员方法（函数）\n",
    "   \n",
    "- 类的基本实现\n",
    "    - 类的命名\n",
    "        -遵守变量命名规范\n",
    "        - 大驼峰（由多个单词构成，每个单词首字母大写）\n",
    "        - 尽量避开跟系统命名相似的命名\n",
    "-你如何声明一个类\n",
    "    -必须用class\n",
    "    - 类由属性和方法构成，其他不能出现\n",
    "    - 成员属性定义可以直接使用变量赋值，如果没有值，可以使用None\n",
    "    - 案例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n",
      "18\n"
     ]
    }
   ],
   "source": [
    "class Student():\n",
    "    pass\n",
    "#定义一个对象\n",
    "mingyue = Student()\n",
    "\n",
    "#定义一个学python 的学生\n",
    "class PythonStu():\n",
    "    name = None\n",
    "    age = 18\n",
    "    course = 'Python'\n",
    "    \n",
    "    def doHomework(slef):\n",
    "        print('我在做作业')\n",
    "        return None\n",
    "#实力化\n",
    "yueyue = PythonStu()\n",
    "print(yueyue.name)\n",
    "print(yueyue.age)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# anaconda基本使用\n",
    "- anaconda主要是一个虚拟环境管理器\n",
    "- 还是一个安装包管理器\n",
    "- conda list：显示anaconda安装的包\n",
    "- conda env list：显示anaconda的虚拟环境列表\n",
    "- conda creat -n xxx python=3.7:创建python版本为3.7的虚拟环境，名称为xxx"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 可以通过默认内置变量检查类和对象的所有成员\n",
    "- 对象所有成员检查\n",
    "\n",
    "        obj.__dict__\n",
    "- 类所有的成员\n",
    "        class_name.__dict__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "mappingproxy({'__module__': '__main__',\n",
       "              'name': 'Cheng',\n",
       "              'age': 28,\n",
       "              '__dict__': <attribute '__dict__' of 'A' objects>,\n",
       "              '__weakref__': <attribute '__weakref__' of 'A' objects>,\n",
       "              '__doc__': None})"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class A():\n",
    "    name = 'Cheng'\n",
    "    age = 28\n",
    "\n",
    "A.__dict__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 类和对象的成员分析\n",
    "- 类和对象都可以存储成员，成员可以归类所有，也可以归对象所有\n",
    "- 类存储成员时使用的是与类关联的对象\n",
    "- 独享存储成员时是存储在当前对象中\n",
    "- 对象访问一个成员时，如果对象中没有该成员，尝试访问类中的同名成员，如果对象中有此成员，一定使用对象中的成员\n",
    "- 创建对象的时候，类中的成员不会放入对象中去，而是得到另一个空对象，没有成员\n",
    "- 通过对象对类中成员重新赋值或者通过对象添加成员时，对应成员会保存在对象中，而不会修改类成员"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cheng\n",
      "28\n",
      "********************\n",
      "4456599312\n",
      "4425606016\n",
      "********************\n",
      "Fei\n",
      "27\n",
      "4456703904\n",
      "4425605984\n"
     ]
    }
   ],
   "source": [
    "class A():\n",
    "    name = 'Cheng'\n",
    "    age =28\n",
    "    \n",
    "    def say(self):\n",
    "        self.name = 'Fei'\n",
    "        self.age = 27\n",
    "    \n",
    "print(A.name)\n",
    "print(A.age)\n",
    "\n",
    "print('*' * 20)\n",
    "\n",
    "print(id(A.name))\n",
    "print(id(A.age))\n",
    "\n",
    "print('*' * 20)\n",
    "a = A()\n",
    "a.say()\n",
    "print(a.name)\n",
    "print(a.age)\n",
    "print(id(a.name))\n",
    "print(id(a.age))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 关于self\n",
    "- self在对象的方法中表示当前对象本身，如果通过对象调用一个方法，那么该对象会自动传入当前方法的第一个参数中\n",
    "- self并不是关键字，只是一个用于接收对象的普通参数，理论上可以用任何一个普通变量代替\n",
    "- 方法中有self形参的方法称为非绑定类的方法，可以通过对象访问，没有self的是绑定类方法，只能通过类访问\n",
    "- 使用类访问绑定类的方法时，如果类方法中需要访问当前类的成员，可以通过__class__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My name is Fei\n",
      "I am 27 years old\n"
     ]
    }
   ],
   "source": [
    "class Student():\n",
    "    name = 'Cheng'\n",
    "    age =28\n",
    "    \n",
    "    def say(self):\n",
    "        self.name = 'Fei'\n",
    "        self.age = 27\n",
    "        print('My name is {0}'.format(self.name))\n",
    "        print('I am {0} years old'.format(self.age))\n",
    "        \n",
    "a = Student()\n",
    "a.say()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My name is Fei\n",
      "I am 27 years old\n",
      "Cheng\n",
      "28\n",
      "Hello,see you again\n"
     ]
    }
   ],
   "source": [
    "class Teacher():\n",
    "    name = 'Cheng'\n",
    "    age = 28\n",
    "    \n",
    "    def say(self):\n",
    "        self.name = 'Fei'\n",
    "        self.age = 27\n",
    "        print('My name is {0}'.format(self.name))\n",
    "        print('I am {0} years old'.format(self.age))\n",
    "        \n",
    "    def sayAgain():\n",
    "        #调用类的成员变量用__class__\n",
    "        print(__class__.name)\n",
    "        print(__class__.age)\n",
    "        print('Hello,see you again')\n",
    "        \n",
    "t = Teacher()\n",
    "t.say()\n",
    "#调用绑定类的函数使用类名\n",
    "Teacher.sayAgain()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 面向对象的三大特性\n",
    "- 封装\n",
    "- 继承\n",
    "- 多态"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 封装\n",
    "- 封装就是对 对象的成员进行访问限制\n",
    "- 封装三个级别\n",
    "    - 公开，public\n",
    "    - 受保护的，protected\n",
    "    - 私有的， private\n",
    "    - public，protected，private不是关键字\n",
    "- 判别对象的位置\n",
    "    - 对象内部\n",
    "    - 对象外部\n",
    "    - 子类中\n",
    "- 私有\n",
    "    - 私有成员是最高级别的封装，只能在当前类或对象中访问\n",
    "    - 在成员前面添加两个下划线\n",
    "    - python的私有不是真的私有，是一种称为name mangling的改名策略，可以使用对象._classname__attribute访问\n",
    "- 受保护的封装 protected\n",
    "    - 受保护的封装是将对象进行一定级别的封装，然后，在类中和子类中都可以访问，但是在外部不行\n",
    "    - 封装方法：在成员名称前面添加一个下划线\n",
    "- 公开的，公共的public\n",
    "    - 公共的封装对成员没有任何操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cheng\n",
      "{'__module__': '__main__', 'name': 'Cheng', '_Person__age': 28, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}\n",
      "28\n"
     ]
    }
   ],
   "source": [
    "class Person():\n",
    "                # name是共有成员\n",
    "                name = 'Cheng'\n",
    "                # __age就是私有成员\n",
    "                __age = 28\n",
    "\n",
    "p = Person()\n",
    "print(p.name)\n",
    "print(Person.__dict__)\n",
    "# 私有的还是有方法可以访问的\n",
    "print(p._Person__age)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 继承\n",
    "- 继承就是一个类可以获得另外一个类的成员属性和成员方法\n",
    "- 减少代码，增加代码的复用性，同时可以设置类与类之间的直接关系\n",
    "- 继承与被继承的概念：\n",
    "    - 被继承的类叫父类，也叫基类，也叫超类\n",
    "    - 用于继承的类，叫子类，也叫派生类\n",
    "    - 继承与被继承存在is-a关系\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cheng\n",
      "NoName\n"
     ]
    }
   ],
   "source": [
    "class Person():\n",
    "    name = 'NoName'\n",
    "    age = 0\n",
    "    def sleep(self):\n",
    "        print('sleeping')\n",
    "\n",
    "# 父类写在括号里\n",
    "class Teacher(Person):\n",
    "    pass\n",
    "\n",
    "t = Teacher()\n",
    "t.name = 'Cheng'\n",
    "print(t.name)\n",
    "print(Teacher.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 继承特征\n",
    "- 所有类都继承自object类\n",
    "- 子类一旦继承父类，就可以使用父类中除私有成员外的所有内容\n",
    "- 子类继承父类后，并没有将父类的成员完全赋值到子类中，而是通过引用关系调用\n",
    "- 子类中可以定义独有的成员属性和方法\n",
    "- 子类中成员如果和父类中成员相同，优先使用子类成员\n",
    "- 子类如果想要扩充父类的方法，可以定义新方法的同时访问父类方法进行代码重组，可以使用 父类名.父类成员  的格式来调用父类成员，也可以使用 super().父类成员的格式来调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "make some money\n",
      "attention\n"
     ]
    }
   ],
   "source": [
    "class Person():\n",
    "    name = 'NoName'\n",
    "    age = 0\n",
    "    __score = 0 # 考试成绩是秘密，自己知道只能\n",
    "    _petname = 'sec' # 小名,是保护的，子类可以用，但不能共用\n",
    "    def sleep(self):\n",
    "        print('sleeping')\n",
    "    def work(self):\n",
    "        print('make some money')\n",
    "\n",
    "# 父类写在括号里\n",
    "class Teacher(Person):\n",
    "    name = 'ming'\n",
    "    age = 28\n",
    "    def make_test(self):\n",
    "        print('attention')\n",
    "    \n",
    "    def work(self):\n",
    "        Person.work(self)\n",
    "        self.make_test()\n",
    "\n",
    "t = Teacher()\n",
    "t.work()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 继承变量的查找顺序\n",
    "- 优先查找自己的变量\n",
    "- 没有查找父类\n",
    "- 构造函数如果本类中没有定义，则自动查找调用父类的构造函数\n",
    "- 本类中有定义构造函数，则不继续向上查找\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 构造函数\n",
    "- 一类特殊的函数，在类进行实例化之前调用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a dog\n"
     ]
    }
   ],
   "source": [
    "class Dog():\n",
    "    # __init__就是构造函数\n",
    "    # 每次实例化的时候第一个被调用\n",
    "    # 主要进行初始化\n",
    "    def __init__(self):\n",
    "        print('a dog')\n",
    "        \n",
    "kavin = Dog()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a dog\n"
     ]
    }
   ],
   "source": [
    "# 继承中的构造函数 -1\n",
    "class Animal():\n",
    "    pass\n",
    "\n",
    "class PaXingAni(Animal):\n",
    "    pass\n",
    "\n",
    "class Dog(PaXingAni):\n",
    "    # __init__就是构造函数\n",
    "    # 每次实例化的时候第一个被调用\n",
    "    # 主要进行初始化\n",
    "    def __init__(self):\n",
    "        print('a dog')\n",
    "        \n",
    "        \n",
    "kaka = Dog()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 继承中的构造函数 -2\n",
    "class Animal():\n",
    "    def __init__(self):\n",
    "        print('animal')\n",
    "\n",
    "class PaXingAni(Animal):\n",
    "    def __init__(self):\n",
    "        print('pa xing')\n",
    "\n",
    "class Dog(PaXingAni):\n",
    "    # __init__就是构造函数\n",
    "    # 每次实例化的时候第一个被调用\n",
    "    # 主要进行初始化\n",
    "    def __init__(self):\n",
    "        print('a dog')\n",
    "        \n",
    "#因为在子类中查找到了构造函数，所以不再向上查找父类的构造函数        \n",
    "kaka = Dog()\n",
    "\n",
    "class Cat(PaXingAni):\n",
    "    pass\n",
    "\n",
    "nini = Cat()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 继承中的构造函数 -3\n",
    "class Animal():\n",
    "    def __init__(self):\n",
    "        print('animal')\n",
    "\n",
    "class PaXingAni(Animal):\n",
    "    def __init__(self, name):\n",
    "        print('pa xing {0}'.format(name))\n",
    "\n",
    "class Dog(PaXingAni):\n",
    "    # __init__就是构造函数\n",
    "    # 每次实例化的时候第一个被调用\n",
    "    # 主要进行初始化\n",
    "    def __init__(self):\n",
    "        print('a dog')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 构造函数\n",
    "- 如果子类没定义，父类的构造函数带参数，则构造对象时的参数应该按父类的参数构造"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# super\n",
    "- super不是关键字，而是一个类\n",
    "- super的作用时获得MRO（MethodResolutionOrder)列表中的第一个类"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
